﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Navigation;
using RATSharp.Model;
using RATSharpW7.ViewModel;
using RATSharpW7.ViewModel.CalendarViewModel;
using RATSharp.Rest;
using System.Threading.Tasks;
using RATSharp.Settings;
using RATSharpW7.Model;
using Microsoft.Phone.Shell;

namespace RATSharpW7.View
{
    /// <summary>
    /// Main menu screen. This screen looks quite simple but in fact it makes a lot of
    /// things.
    /// 
    /// 1)it listens to all app properties. In case when user change app settings it will 
    /// try co connect to server with new settings and set UserContext (which is widely used in APP)
    /// In case when something fails it at least disable all buttons which corresponding screens requires some
    /// kind of communication
    /// 
    /// 2) handles pickUpAction (see handlePickAction method)
    /// 3) handles results from object browser and show object profile in case user select something in it
    /// 
    /// </summary>
    public partial class MainMenu : PhoneApplicationPage
    {
        private static bool pickUpClicked;
        public static bool PickUpClicked
        {
            get
            {
                bool old = pickUpClicked;
                pickUpClicked = false;
                return old;
            }
        }
        private ApplicationBarMenuItem objectBrowserMenuItem;
        bool isNewPageInstance = false;
        UserViewModel model;

        public MainMenu()
        {
            InitializeComponent();
            isNewPageInstance = true;
        }

        private void initActionBar()
        {
            ApplicationBarMenuItem settingsMenuItem = new ApplicationBarMenuItem(Application.Current.Resources["SettingsButtonLabel"] as string);
            settingsMenuItem.Click += SettingsButton_Click;
            ApplicationBar.MenuItems.Add(settingsMenuItem);

            objectBrowserMenuItem = new ApplicationBarMenuItem(Application.Current.Resources["ObjectBrowserLabel"] as string);
            objectBrowserMenuItem.Click += ObjectBrowserButton_Click;
            ApplicationBar.MenuItems.Add(objectBrowserMenuItem);
        }

        private void enableButtons(bool enabled)
        {
            foreach(ApplicationBarIconButton button in  this.ApplicationBar.Buttons) 
            {
                button.IsEnabled = enabled;
            }
            objectBrowserMenuItem.IsEnabled = enabled;
        }

        private void PickUpButton_Click(object sender, EventArgs e)
        {
            pickUpClicked = true;
            NavigationService.Navigate(new Uri("/View/ObjectBrowser.xaml", UriKind.Relative));
        }

        private void CalendarButton_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate("View", typeof(Calendar), new CalendarUserDataFactory());
        }

        private void ObjectBrowserButton_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/View/ObjectBrowser.xaml", UriKind.Relative));
        }

        private void SettingsButton_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate("View", typeof(RATSharp.View.Settings), new EventHandler(userSettingsChangedHandler));
        }

        private void FavouriteButton_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/View/Favourites.xaml", UriKind.Relative));
        }

        private void ReturnitbackButton_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri("/View/ReturnItBack.xaml", UriKind.Relative));
        }


        private void userSettingsChangedHandler(object sender, EventArgs args)
        {
            RestService.restore();
            UserViewModel.UserContext = null;
        }


        private void userLoadedHandler(object sender, ModifyReservationEventArgs e)
        {
            if (!e.succesfull)
            {
                ViewUtils.reportError(e.message);
                enableButtons(false);
            }
            else
            {
                ViewUtils.reportMessage(Application.Current.Resources["MessageLoggedAs"] as string + " " + UserViewModel.UserContext.Name);
                enableButtons(true);
                checkPropertiesLoaded();
            }
        }

        private void checkPropertiesLoaded()
        {
            AppSettings settings = new AppSettings();
            if (settings.PropertiesSettings == null)
            {
                Task<Properties> task = RestService.getInstance().getProperties();
                task.ContinueWith(t =>
             {
                 if (t.Exception != null || t.Result == null)
                 {
                     ViewUtils.reportError(t.Exception != null ? t.Exception.Message : "unknown");
                 }
                 else
                 {
                     settings.PropertiesSettings = t.Result;
                 }
             });
            }
        }

        private void handlePickAction(RATSharp.Model.Object obj)
        {
            if (!obj.pickable)
            {
                ViewUtils.reportMessage(Application.Current.Resources["MessageNotPickable"] as string);
                return;
            }

            Task<Reservations> task = RestService.getInstance().pickUpObject(obj.id);

            task.ContinueWith(t =>
            {
                //switch to UI thread
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    if (t.Exception != null || t.Result == null)
                    {
                        ViewUtils.reportError(t.Exception != null ? t.Exception.Message : "unknown");
                    }

                    else if (t.Result.Count > 0)
                    {
                        ViewUtils.reportMessage(Application.Current.Resources["MessageObjectPicked"] as string);
                        return;
                    }
                    else
                    {
                        RATSharp.Model.ReservationFactory.CreateReservationData data = new RATSharp.Model.ReservationFactory.CreateReservationData();
                        data.obj = obj;
                        data.selectedDate = DateTime.Now;
                        data.pickAction = PickAction.PICKED;
                        NavigationService.Navigate("View", typeof(CreatePickUpReservation), data);
                    }
                });
            });
        }
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (isNewPageInstance)
            {
                if (model == null)
                {
                    if (State.ContainsKey("UserViewModel"))
                    {
                        model = State["UserViewModel"]
                                           as UserViewModel;
                    }
                    else
                    {
                        model = new UserViewModel();
                    }
                }
                DataContext = model;
                initActionBar();
            }
            else
            {
                RATSharp.Model.Object obj = ObjectBrowser.SelectedObject;
                if (obj != null)
                {
                    if (PickUpClicked)
                    {
                        handlePickAction(obj);
                    }
                    else
                    {
                        NavigationService.Navigate("View", typeof(ObjectProfile), obj);
                    }
                    isNewPageInstance = false;
                    return;
                }

            }
            if (UserViewModel.UserContext == null)
            {
                model.loadUser((new AppSettings()).UsernameSetting, new EventHandler<ModifyReservationEventArgs>(userLoadedHandler));
            }
            isNewPageInstance = false;
        }
    }
}